package com.github.niefy.modules.wx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.niefy.modules.sys.entity.SysUserEntity;
import com.github.niefy.modules.wx.dao.WxArticleMapper;
import com.github.niefy.modules.wx.dto.PageSizeConstant;
import com.github.niefy.modules.wx.entity.WxAccount;
import com.github.niefy.modules.wx.entity.WxArticle;
import com.github.niefy.modules.wx.enums.ArticleTypeEnum;
import com.github.niefy.modules.wx.service.ArticleService;
import com.github.niefy.common.utils.PageUtils;
import com.github.niefy.common.utils.Query;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftArticles;
import me.chanjar.weixin.mp.bean.freepublish.WxMpFreePublishStatus;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author Nifury
 * @date 2017-10-27
 */
@Service
@EnableCaching
@CacheConfig(cacheNames = {"ArticleServiceCache"})
@Slf4j
@EnableScheduling
public class ArticleServiceImpl extends ServiceImpl<WxArticleMapper, WxArticle> implements ArticleService {
    private static final String ID_PLACEHOLDER = "${articleId}";
    /**
     * 查询文章列表时返回的字段（过滤掉详情字段以加快速度）
     */
    private static final String LIST_FILEDS = "id,title,author,digest,url,is_deleted,state,release_time";

    public static final String CACHE_KEY="'WX_ARTICLE_TAGS'";

    public String appid = "";

    public boolean ScheduledStatus = false;

    @Autowired
    WxArticleMapper wxArticleMapper;

    @Autowired
    WxMpService wxMpService;

    @Autowired
    WxDraftServiceImpl wxDraftServiceImpl;


    @Override
    public PageUtils queryPage(String appid,Map<String, Object> params) {
        String title = (String) params.get("title");
        String isDeleted = (String) params.get("isDeleted");
        String state = (String) params.get("state");
        IPage<WxArticle> page = this.page(
            new Query<WxArticle>().getPage(params),
            new QueryWrapper<WxArticle>()
                .select(LIST_FILEDS)
                .like(StringUtils.hasText(title), "title", title)
                    .eq(StringUtils.hasText(isDeleted), "is_deleted", isDeleted)
                    .eq(StringUtils.hasText(state), "state", state)
                    .eq("appid",appid).orderByDesc("release_time")
        );
        return new PageUtils(page);
    }

    /**
     * 添加或编辑文章,同名文章不可重复添加
     *
     */

    @Override
    public boolean saveArticle(String appid,WxMpDraftArticles wxMpDraftArticles) throws WxErrorException {
        WxArticle wxArticle = new WxArticle();
        String mediaId = wxDraftServiceImpl.draftUpload(appid,wxMpDraftArticles).getMediaId().replace("\"", "");;
        String publishId = wxDraftServiceImpl.submit(mediaId);
        int status = wxDraftServiceImpl.getPushStatus(publishId).getPublish_status();

        wxArticle.setAuthor(((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername().toString());
        wxArticle.setContent(wxMpDraftArticles.getContent());
        wxArticle.setDigest(wxMpDraftArticles.getDigest());
        wxArticle.setIsDeleted(false);
        wxArticle.setContentSourceUrl(wxMpDraftArticles.getContentSourceUrl());
        wxArticle.setNeedOpenComment(wxMpDraftArticles.getNeedOpenComment());
        wxArticle.setOnlyFansCanComment(wxMpDraftArticles.getOnlyFansCanComment());
        wxArticle.setShowCoverPic(wxMpDraftArticles.getShowCoverPic());
        wxArticle.setThumbMediaId(wxMpDraftArticles.getThumbMediaId());
        wxArticle.setTitle(wxMpDraftArticles.getTitle());
        wxArticle.setAppid(appid);
        wxArticle.setMediaId(mediaId);
        wxArticle.setPublishId(publishId);
        wxArticle.setState(String.valueOf(status));
        wxArticle.setReleaseTime(new Date());
        wxArticleMapper.insert(wxArticle);
        this.ScheduledStatus=true;
        this.appid=appid;
        roundCheck();

//        article.setUpdateTime(new Date());
//        if (null != article.getId() && article.getId() > 0) {
//            articleMapper.updateById(article);
//        } else {
//            String title = article.getTitle();
//            long count = articleMapper.selectCount(
//                new QueryWrapper<Article>().eq("title", title)
//                    .eq("category", article.getCategory())
//                    .eq("sub_category", article.getSubCategory())
//            );
//            if (count > 0) {
//                throw new RRException("同目录下文章[" + title + "]已存在，不可重复添加");
//            }
//            article.setCreateTime(new Date());
//            articleMapper.insert(article);
//        }
//        String targetLink = article.getTargetLink();
//        if (targetLink.indexOf(ID_PLACEHOLDER) > -1) {
//            article.setTargetLink(targetLink.replace(ID_PLACEHOLDER, article.getId() + ""));
//            articleMapper.updateById(article);
//        }
        return true;
    }

    /**
     * 按条件分页查询
     *
     * @param title
     * @param page
     * @return
     */
    @Override
    public IPage<WxArticle> getArticles(String title, int page) {
        return this.page(new Page<WxArticle>(page, PageSizeConstant.PAGE_SIZE_SMALL),
            new QueryWrapper<WxArticle>().like(StringUtils.hasText("title"), "title", title)
                .select(LIST_FILEDS)
                .orderBy(true, false, "update_time"));
    }

    /**
     * 查看目录，不返回文章详情字段
     *
     * @param articleType
     * @param category
     * @return
     */
    @Override
    public List<WxArticle> selectCategory(ArticleTypeEnum articleType, String category) {
        return this.list(new QueryWrapper<WxArticle>()
            .select(LIST_FILEDS)
            .eq("type", articleType.getValue())
            .eq("category", category));
    }

    /**
     * 文章查找，不返回文章详情字段
     *
     * @param articleType
     * @param category
     * @param keywords
     * @return
     */
    @Override
    public List<WxArticle> search(ArticleTypeEnum articleType, String category, String keywords) {
        return this.list(new QueryWrapper<WxArticle>()
            .select(LIST_FILEDS)
            .eq("type", articleType.getValue())
            .eq(StringUtils.hasText(category), "category", category)
            .and(i -> i.like("summary", keywords).or().like("title", keywords)));
    }

    @Override
    public boolean remove(Integer[] ids) throws WxErrorException {
        List<WxArticle> list = this.listByIds(Arrays.asList(ids));
        for (WxArticle wxArticle:
        list) {
//            wxMpService.getFreePublishService().deletePushAllArticle(wxArticle.getArticleId());
            wxMpService.getDraftService().delDraft(wxArticle.getMediaId());
        }
        this.removeByIds(Arrays.asList(ids));
        return true;
    }

    @Async
    public void getStatus() throws WxErrorException {
        if(this.ScheduledStatus){
        List<WxArticle> list = getList(this.appid);
        log.debug("剩余文章数"+String.valueOf(list.size()));
        if(list.size()!=0){
            for (WxArticle wxArticle:list) {
                WxMpFreePublishStatus wxMpFreePublishStatus = wxDraftServiceImpl.getPushStatus(wxArticle.getPublishId());
                if(wxMpFreePublishStatus.getPublish_status()==0){
                    log.debug(wxArticle.getTitle()+"发布成功");
                    this.list().remove(wxArticle);
                    wxArticle.setArticleId(wxMpFreePublishStatus.getArticle_id());
                    wxArticle.setState(String.valueOf(wxMpFreePublishStatus.getPublish_status()));
                    wxArticle.setUrl(wxMpFreePublishStatus.getArticle_detail().getItem().get(0).getArticle_url());
                    updateById(wxArticle);
                }else if (wxMpFreePublishStatus.getPublish_status()!=1){
                    this.list().remove(wxArticle);
                    log.debug(wxArticle.getTitle()+"发布失败");
                    wxArticle.setState(String.valueOf(wxMpFreePublishStatus.getPublish_status()));
                    updateById(wxArticle);
                }
            }
        }else {
            this.ScheduledStatus=false;
        }
        }
    }

    public List<WxArticle> getList(String appid) {
        return this.list(new QueryWrapper<WxArticle>().eq("state","1").eq("appid",appid));
    }

    public boolean updateById(WxArticle wxArticle) {
        wxArticleMapper.updateById(wxArticle);
        return false;
    }

    @Scheduled(fixedRate = 1000*60*5)
//    @Scheduled(fixedRate = 1000)
    public void roundCheck() throws WxErrorException {
        if(this.appid!=""){
            getStatus();
        }
    }

}
